package com.jt.controller;

import com.jt.SecurityMain.LoginUser;
import com.jt.dto.UserPageDto;
import com.jt.enums.SysLogEnum;
import com.jt.pojo.Result;
import com.jt.pojo.Menu;
import com.jt.pojo.User;
import com.jt.service.RoleService;
import com.jt.service.MenuService;
import com.jt.service.UserService;
import com.jt.utils.JwtUtils;
import com.jt.utils.MenuUtils;
import com.jt.utils.RedisUtils;
import com.jt.utils.log.SysLogAnnotation;
import com.jt.vo.MenuVo;
import com.jt.vo.UserPageVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService routerService;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private RedisUtils redisUtils;

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private MenuUtils menuUtils;

    /**
     * 查询所有用户
     *
     * @param
     * @return Result
     */
    @RequestMapping("/selectAllUserList")
    @SysLogAnnotation(operModul = "用户模块", operType = SysLogEnum.OTHER, operDesc = "查询所有用户信息")
    public Result selectAllUserList() {
        List<User> list = userService.selectAllUserList();
        return new Result().setData(list).setCode(200).setMasege("查询所有list");
    }


    /**
     * 用户退出登录
     *
     * @param
     * @return Result
     */
    @RequestMapping("/loginOut")
    public Result loginOut() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        LoginUser loginUser = (LoginUser) authentication.getPrincipal();
        User user = loginUser.getUser();
        redisUtils.del ("token:"+user.getId());
        return new Result().setData(null).setCode(200).setMasege("退出登录成功");
    }

    /**
     * 用户登录
     *
     * @param user 用户
     * @return Result
     */
    @RequestMapping("/login")
    @SysLogAnnotation(operDesc = "用户登录", operType = SysLogEnum.OTHER, operModul = "用户登录")
    public Result login(@RequestBody User user) {
        UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = new UsernamePasswordAuthenticationToken(user.getName(), user.getPassWold());
        Authentication authenticate = authenticationManager.authenticate(usernamePasswordAuthenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("登陆失败");
        }
        LoginUser loginUser =    (LoginUser) authenticate.getPrincipal();
        User userAuthenticate = loginUser.getUser();
        if (!Objects.isNull(userAuthenticate)) {
            String token = JwtUtils.getToken(userAuthenticate);
            Map<String, Object> map = new HashMap<>();
            /*查询当前用户的所有菜单信息和权限信息*/
            String userId = userAuthenticate.getId();
            Map<String, Object> menuResultMap = userService.selectMenuList(userId);
            map.put("menuResultMap",menuResultMap);
            map.put("token", token);
            Map<String, Object> redisMap = new HashMap<>();
            redisMap.put("loginUser", loginUser);
            String key = "loginUser:" + userAuthenticate.getId();
            redisUtils.hmset(key, redisMap, 60000l);
            return new Result().setData(map).setCode(200).setMasege("登陆成功");
        }
        return new Result().setData(null).setCode(200).setMasege("没有此用户");
    }

    /**
     * 将menulist转换成没有id的路由菜单。直接使用
     *
     * @param routerList
     * @return Result
     */
    @RequestMapping("/changeMenu")
    @PreAuthorize("hasAnyAuthority('system:user:update')")
    public Result getMenu(@RequestBody List<Menu> routerList) {
        List<MenuVo> resultRouter = menuUtils.resultRouter(routerList);
        return new Result().setData(resultRouter).setCode(200).setMasege("转换路由菜单成功");
    }

    /**
     * 用户新增
     *
     * @param user
     * @return Result
     */
    @PostMapping("/insert")
    public Result insert(@RequestBody User user) {
        user.setPassWold(passwordEncoder.encode(user.getPassWold()));
        boolean trueAndFalse = userService.insert(user);
        if (!trueAndFalse) {
            return new Result().setData(false).setCode(200).setMasege("新增失败");
        }
        return new Result().setData(true).setCode(200).setMasege("新增成功");
    }

    /**
     * 用户分页列表
     *
     * @param userPageDto
     * @return userPageVo
     */
    @PostMapping("/pageList")
    @PreAuthorize("hasAnyAuthority('system:user:list')")
    @SysLogAnnotation(operDesc = "用户分页列表", operType = SysLogEnum.SELECT, operModul = "用户分页列表")
    public Result UserPageList(@RequestBody UserPageDto userPageDto) {
        userPageDto.setPageNumber((userPageDto.getPageNumber() - 1) * userPageDto.getPageSize());
        List<User> userList = userService.UserPageList(userPageDto);
        int total = userService.UserTotal(userPageDto);
        log.info("用户列表数据:{}和总条数:{}", userList, total);
        UserPageVo userPageVo = new UserPageVo();
        userPageVo.setUser(userList);
        userPageVo.setTotal(total);
        return new Result().setData(userPageVo).setCode(200).setMasege("分页查询成功");
    }

    /**
     * 通过token获取用户信息
     *
     * @param
     * @return userPageVo
     */
    @GetMapping("/getUserNameByToken")
    public String getUserNameByToken(String token) {
        Map<String, Object> map = JwtUtils.JieXi(token);
        return map.get("username").toString();
    }

    /**
     * Assign permissions给用户分配角色
     */
    @GetMapping("/AssignPermissions")
    public Result AssignPermissions(String checkedRoles, String userId) {
        boolean yesAndNo = userService.AssignPermissions(checkedRoles ,userId);
        if (!yesAndNo) {
            return new Result().setData(null).setMasege("分配角色失败").setCode(500);
        }
        return new Result().setData(null).setMasege("分配角色成功").setCode(200);
    }

    /**
     * delete删除用户
     */
    @GetMapping("/deleteById")
    @PreAuthorize("hasAnyAuthority('system:user:update')")
    public Result deleteUser(@RequestParam("userId") String userId) {
        boolean deleteCount = userService.deleteById(userId);
        if (deleteCount) {
            return new Result().setData(null).setMasege("删除成功").setCode(200);
        }
        return new Result().setData(null).setMasege("分配角色成功").setCode(500);
    }
}
